package cn.t.facade.user;


import cn.t.converter.user.ParticipantInfoDTOConverter;
import cn.t.core.exception.BizException;
import cn.t.core.facade.FacadeImpl;
import cn.t.core.mode.YesNoEnum;
import cn.t.dto.user.ParticipantInfoDTO;
import cn.t.core.enums.base.BaseStatusEnum;
import cn.t.core.enums.base.CommonError;
import cn.t.enums.user.UpdateEventTypeEnum;
import cn.t.model.user.CostCenterDO;
import cn.t.model.user.CustomerFirmDO;
import cn.t.model.user.ParticipantInfoDO;
import cn.t.model.user.UserInfoDO;
import cn.t.service.user.CostCenterService;
import cn.t.service.user.CustomerFirmService;
import cn.t.service.user.ParticipantInfoService;
import cn.t.service.user.ParticipantRoleService;
import cn.t.service.user.UserInfoService;
import cn.t.user.event.UserQueryUpdateEvent;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 参与者信息表服务编排
 *
 * @author l
 */
@Slf4j
@Service
@AllArgsConstructor
public class ParticipantInfoFacade extends FacadeImpl<ParticipantInfoDTO, ParticipantInfoDO, ParticipantInfoDTOConverter, ParticipantInfoService> {


    @Transactional
    public Boolean bindFirm(Long userId, Long firmId, Long individualId, Long costCenterId) {

        CustomerFirmDO firm = customerFirmService.findById(firmId);
        if (firm == null || !firmId.equals(firm.getId())) {
            String errorMessage = String.format("指定的公司不存在 firmId=%d ", firmId);
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }

        if (costCenterId != null && costCenterId > 0) {
            CostCenterDO costCenter = costCenterService.findById(costCenterId);
            if (costCenter == null || !firmId.equals(costCenter.getFirmId())) {
                String errorMessage = String.format("指定的成本中心不存在 firmId=%d ", firmId);
                log.error(errorMessage);
                throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
            }
        }


        List<ParticipantInfoDO> participantInfos = service.findByUserId(userId);
        if (!CollectionUtils.isEmpty(participantInfos)) {
            Set<Long> existsFirmIds = participantInfos.stream().map(ParticipantInfoDO::getFirmId).collect(Collectors.toSet());
            if (existsFirmIds.contains(firmId)) {
                applicationEventPublisher.publishEvent(new UserQueryUpdateEvent(userId, userSessionFacade.operatorInfo(), userId, UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.NONE));
                return true;
            }
        }
        service.getOrAdd(userId, individualId, firmId);

        applicationEventPublisher.publishEvent(new UserQueryUpdateEvent(userId, userSessionFacade.operatorInfo(), userId, UpdateEventTypeEnum.NONE, UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.NONE));

        return true;

    }

    @Transactional
    public Boolean unbindFirm(Long userId, Long firmId) {

        List<ParticipantInfoDO> participantInfos = service.findByUserFirm(userId, firmId);
        if (CollectionUtils.isEmpty(participantInfos)) {
            applicationEventPublisher.publishEvent(new UserQueryUpdateEvent(userId, userSessionFacade.operatorInfo(), userId, UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.NONE));
            return true;
        }

        participantInfos.forEach(participantInfoDO -> {
            participantRoleService.removeByParticipantId(participantInfoDO.getId());
        });

        applicationEventPublisher.publishEvent(new UserQueryUpdateEvent(userId, userSessionFacade.operatorInfo(), userId, UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.NONE));

        return true;
    }

    public Boolean bindCostCenter(@RequestParam Long userId, @RequestParam Long costCenterId) {
        UserInfoDO userInfoDO = userInfoService.findById(userId);
        if (userInfoDO == null
                || !String.valueOf(BaseStatusEnum.AVAILABLE.getCode()).equals(userInfoDO.getUserStatus())
                || !YesNoEnum.FALSE.equals(userInfoDO.getIsDeleted())) {
            String errorMessage = String.format("指定的用户不存在 userId=%d ", userId);
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }

        service.getOrAddByCostCenter(userId, userInfoDO.getIndividualId(), costCenterId);

        applicationEventPublisher.publishEvent(new UserQueryUpdateEvent(userId, userSessionFacade.operatorInfo(), userId, UpdateEventTypeEnum.NONE, UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.NONE));

        return true;
    }

    public Boolean unbindCostCenter(@RequestParam Long userId, @RequestParam Long costCenterId) {
        ParticipantInfoDO participantInfoDO = service.findByUserCostCenter(userId, costCenterId);
        if (participantInfoDO == null) {
            return true;
        }
        service.unbindCostCenter(participantInfoDO.getId());

        applicationEventPublisher.publishEvent(new UserQueryUpdateEvent(userId, userSessionFacade.operatorInfo(), userId, UpdateEventTypeEnum.NONE, UpdateEventTypeEnum.UPDATE, UpdateEventTypeEnum.NONE));

        return true;
    }


    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @Autowired
    private UserSessionFacade userSessionFacade;

    @Autowired
    private ParticipantRoleService participantRoleService;

    @Autowired
    private CustomerFirmService customerFirmService;

    @Autowired
    private CostCenterService costCenterService;

    @Autowired
    private UserInfoService userInfoService;


}

